/*
 * Created on Sep 19, 2007
 * 
 */

package com.probiz.estore.core.filter;

import java.io.IOException;
import java.util.Set;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.acegisecurity.Authentication;
import org.acegisecurity.context.SecurityContextHolder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;

import com.probiz.estore.core.exception.AccessDeniedException;
import com.probiz.estore.system.service.AppRoleManager;

/**
 * 问题：Acegi原来的设计相当复杂，而URL-Role的管理方式不方便（每增加一个URL需要对每个需要访问的角色都明确授权）。
 * 修改：大大简化，不需要的内容全部去掉包括身份认证等，因为前面已经有其他filter，无须再次处理；去掉event机制，减少抛出exception，因而也更高效。
 * 
 * @author Legend
 * 
 */
public class FilterSecurityInterceptor implements Filter {
	private static final String	FILTER_APPLIED	= "__probiz_filterSecurityInterceptor_filterApplied";

	protected static final Log	logger			= LogFactory
														.getLog(FilterSecurityInterceptor.class);

	AppRoleManager				roleMgr;

	protected void checkIsUrlAuthorized(String url) {
		Assert.notNull(url, "Url was null");

		// 要求先身份认证了，否则抛出，因为前面已经有Filter做过类似的认证了
		if (!SecurityContextHolder.getContext().getAuthentication()
				.isAuthenticated()) {
			throw new AccessDeniedException("Not authenticated!");
		}

//		Authentication authenticated = SecurityContextHolder.getContext().getAuthentication();
		// TODO 可能要处理匿名用户的问题

		// 进行授权检查，如果失败，抛出AccessDeniedException
//		if (!isUrlGrantedForUser(authenticated, url)) {
//			throw new AccessDeniedException("Access is denied! Url:" + url + " User:" + authenticated.getName());
//		}

		if (logger.isDebugEnabled()) {
			logger.debug("Authorization successful");
		}

	}

	public void destroy() {

	}

	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		if (request.getAttribute(FILTER_APPLIED) == null) {
			// first time this request being called, so perform security
			// checking
			request.setAttribute(FILTER_APPLIED, Boolean.TRUE);

			String url = ((HttpServletRequest) request).getRequestURI();
			// TO doaction处理；如果没有权限，该方法里面会抛出Exception。
			checkIsUrlAuthorized(url);
		}
		chain.doFilter(request, response);
	}
//
//	protected Set<String> getRoleResource(Integer roleId) {
//		return roleMgr.getById(roleId).getResources();
//	}
//

//
//	protected boolean isUrlGrantedForRole(Integer roleId, String url) {
//		//用正则表达式测试Role所有授权的url，如果匹配返回true，否则最后返回false
//		if (getRoleResource(roleId).contains(url)) {
//			return true;
//		}
//		return false;
//	}
//
//	protected boolean isUrlGrantedForUser(Authentication authentication,
//			String url) {
//		// Attempt to find a matching granted authority
//		for (int i = 0; i < authentication.getAuthorities().length; i++) {
//			if (isUrlGrantedForRole(Integer.parseInt(authentication.getAuthorities()[i].getAuthority()), url)) {
//				return true;
//			}
//		}
//		return false;
//	}

	public void setRoleManager(AppRoleManager roleMgr) {
		this.roleMgr = roleMgr;
	}
	public void init(FilterConfig filterConfig) throws ServletException {

	}
}
